package com.sim.server;

import com.sim.core.ImEnvironment;
import com.sim.core.utils.Prop;
import com.sim.server.command.SimWsHandshakeProcessor;
import com.sim.server.listener.ImGroupListener;
import com.sim.server.listener.ImUserListener;
import com.sim.server.service.LoginServiceProcessor;
import org.apache.commons.lang3.StringUtils;
import com.sim.core.packets.Command;
import com.sim.core.utils.PropUtil;
import com.sim.server.command.CommandManager;
import com.sim.server.command.handler.ChatReqHandler;
import com.sim.server.command.handler.HandshakeReqHandler;
import com.sim.server.command.handler.LoginReqHandler;
import com.sim.server.config.ImServerConfig;
import com.sim.server.config.PropertyImServerConfigBuilder;
import com.sim.server.processor.chat.DefaultAsyncChatMessageProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ssl.SslConfig;
import java.util.HashMap;
import java.util.Map;

public class ImServerApplication {
    private static final Logger LOG = LoggerFactory.getLogger(ImServerApplication.class.getName());

    public static void main(String[] args)throws Exception {
        //加载application.properties
        Prop prop = PropUtil.use("application.properties");
        String env = prop.getProperties().getProperty("spring.profiles.active","");
        if(StringUtils.isNotBlank(env)){
            ImEnvironment.ENV = env;
        }

        //加载命令中获取参数
        Map<String,String> params = new HashMap<>();
        if(args.length > 0){
            for (int i=0;i<args.length;i++) {
                if(args[i].contains("=")){
                    String[] kv = args[i].split("=");
                    params.put(kv[0],kv[1]);
                }
            }
        }
        //参数名spring.profiles.active是为了统一
        if(params.containsKey("--spring.profiles.active")){
            ImEnvironment.ENV = params.get("--spring.profiles.active");
        }

        ImServerConfig imServerConfig = new PropertyImServerConfigBuilder("application.properties").build();
        LOG.info("The following profiles are active: {}",ImEnvironment.ENV);
        //初始化SSL;(开启SSL之前,你要保证你有SSL证书哦...)
        initSsl(imServerConfig);
        //设置群组监听器，非必须，根据需要自己选择性实现;
        imServerConfig.setImGroupListener(new ImGroupListener());
        //设置绑定用户监听器，非必须，根据需要自己选择性实现;
        imServerConfig.setImUserListener(new ImUserListener());
        SimServer simServer = new SimServer(imServerConfig);

        /*****************start 以下处理器根据业务需要自行添加与扩展，每个Command都可以添加扩展,此处为demo中处理**********************************/

        HandshakeReqHandler handshakeReqHandler = CommandManager.getCommand(Command.COMMAND_HANDSHAKE_REQ, HandshakeReqHandler.class);
        //添加自定义握手处理器;
        handshakeReqHandler.addMultiProtocolProcessor(new SimWsHandshakeProcessor());
        LoginReqHandler loginReqHandler = CommandManager.getCommand(Command.COMMAND_LOGIN_REQ, LoginReqHandler.class);
        //添加登录业务处理器;
        loginReqHandler.setSingleProcessor(new LoginServiceProcessor());
        //添加用户业务聊天记录处理器，用户自己继承抽象类BaseAsyncChatMessageProcessor即可，以下为内置默认的处理器！
        ChatReqHandler chatReqHandler = CommandManager.getCommand(Command.COMMAND_CHAT_REQ, ChatReqHandler.class);
        chatReqHandler.setSingleProcessor(new DefaultAsyncChatMessageProcessor());
        /*****************end *******************************************************************************************/
        simServer.start();
    }

    /**
     * 开启SSL之前，你要保证你有SSL证书哦！
     * @param imServerConfig
     * @throws Exception
     */
    private static void initSsl(ImServerConfig imServerConfig) throws Exception {
        //开启SSL
        if(ImServerConfig.ON.equals(imServerConfig.getIsSSL())){
            String keyStorePath = PropUtil.get("sim.key.store.path");
            String keyStoreFile = keyStorePath;
            String trustStoreFile = keyStorePath;
            String keyStorePwd = PropUtil.get("sim.key.store.pwd");
            if (StringUtils.isNotBlank(keyStoreFile) && StringUtils.isNotBlank(trustStoreFile)) {
                SslConfig sslConfig = SslConfig.forServer(keyStoreFile, trustStoreFile, keyStorePwd);
                imServerConfig.setSslConfig(sslConfig);
            }
        }
    }
}
